<template>
  <div id="WebGL-output"></div>
  <div id="Stats-output"></div>
</template>

<script setup>
import {getCurrentInstance, onMounted, reactive} from 'vue';
import {TrackballControls} from 'three/examples/jsm/controls/TrackballControls';
import Stats from 'three/examples/jsm/libs/stats.module';
import {gui as dat} from 'dat.gui';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';

let {proxy} = getCurrentInstance();
let THREE = proxy.$THREE;
let controls = reactive({
  rotationSpeed: null,
  wireframe: '',
  color: '',
  gridHelper: false,
  backGround: '0x050505'
})
onMounted(() => {
  // 初始化性能插件
  const stats = initStats();
  // 创建一个场景（场景是一个容器，用于保存、跟踪所要渲染的物体和使用的光源）
  const scene = new THREE.Scene();
  // 创建一个摄像机对象（摄像机决定了能够在场景里看到什么）--透视相机
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
  // 创建WebGl渲染器
  const renderer = new THREE.WebGLRenderer();

  // 配置渲染器
  renderer.antialias = true;// 抗锯齿
  renderer.autoClear = true;// 自动清除
  renderer.setClearColor(0x050505);// 渲染背景色
  renderer.setSize(window.innerWidth, window.innerHeight);// 渲染范围

  // 配置相机
  camera.position.set(0, 400, 800);// 相机在三维空间的位置
  camera.lookAt(new THREE.Vector3(0, 0, 0));// 相机看向空间坐标原点

  // 创建立方体
  const cubeGeometry = new THREE.BoxGeometry(100, 100, 100);// 立方体模型
  const cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});// 立方体材质,颜色为随机色
  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);// 创建网格实例
  cube.position.y = 90;// 立方体的 y 坐标 +90
  // 将立方体加入场景
  scene.add(cube);

  // 创建光源 ambientLight:环境光、directionalLight:平行光
  const ambientLight = new THREE.AmbientLight(0x404040);
  const directionalLight1 = new THREE.DirectionalLight(0xC0C090);
  const directionalLight2 = new THREE.DirectionalLight(0xC0C090);
  // 设置光源的位置
  directionalLight1.position.set(-300, -400, 300);
  directionalLight2.position.set(300, 400, -300);
  // 将光源加入场景
  scene.add(ambientLight);
  scene.add(directionalLight1);
  scene.add(directionalLight2);

  // 创建网格辅助
  const gridHelper = new THREE.GridHelper(1200, 50, 0xFF4444, 0x404040);
  scene.add(gridHelper);

  // 创建轨迹球控件
  const trackballControls = new TrackballControls(camera, renderer.domElement);

  // 将渲染器添加到画布
  document.getElementById('WebGL-output').append(renderer.domElement);

  // 窗口大小改变触发的方法
  function onWindowResize() {
    // 改变相机的 aspect 为窗口的宽和长度之比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 更新相机的投影矩阵
    camera.updateProjectionMatrix();
    // 重新设置渲染器的大小
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  // 添加事件监听
  window.addEventListener('resize', onWindowResize, false);

  // 初始化性能插件方法
  function initStats() {
    const stats = new Stats();

    stats.setMode(0);// 0:现实fps, 1:ms

    // 调整插件布局
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0px';
    stats.domElement.style.top = '0px';
    // 加入画布
    document.getElementById('Stats-output').append(stats.domElement);
    // 将初始化的插件返回
    return stats;
  }

  // 添加控制器
  function initControls() {
    controls = new OrbitControls(camera, renderer.domElement)
    controls.rotationSpeed = 0.02;
    controls.wireframe = cubeMaterial.wireframe;
    controls.color = cubeMaterial.color.getStyle();
    controls.gridHelper = false;
    // 这边设置背景色总会报错，还不知道怎么解决
    // controls.value.backGround = renderer.getClearColor().getHex()
  }
  initControls()

  // 初始化GUI
  function initGUI() {
    // 创建图形调试控件
    const gui = new dat.GUI({autoPlace: false});
    // 添加id
    gui.domElement.id = 'gui-box';

    // 创建 helperGui 目录,下面包含 gridHelper 组件
    const helperGui = gui.addFolder('Helper');
    helperGui.add(controls, 'gridHelper').onChange(function (e) {
      console.log(e);
      if (e) {
        scene.remove(gridHelper);
      } else {
        scene.add(gridHelper);
      }
    });

    // 创建 meshGui 目录, 目录下包含组件 wireframe、color、rotationSpeed
    const meshGui = gui.addFolder('Mesh');
    meshGui.add(controls, 'wireframe').onChange(function (e) {
      cubeMaterial.wireframe = e;
    });
    meshGui.addColor(controls, 'color').onChange(function (e) {
      cubeMaterial.color.setStyle(e);
    })
    meshGui.add(controls, 'rotationSpeed', 0, 0.1);

    // 创建 sceneGui 目录, 目录下包含 backGround 组件
    /*const sceneGui = gui.addFolder('Scene');
    sceneGui.addColor(controls, 'backGround').onChange(function (e) {
      renderer.setClearColor(e)
    })*/

    // 调整插件布局
    gui.domElement.style.position = 'absolute';
    gui.domElement.style.right = '0px';
    gui.domElement.style.top = '50px';
    // 加入画布
    document.getElementById('WebGL-output').append(gui.domElement);
  }
  initGUI()

  // 渲染方法
  function render() {
    // 更新性能插件
    stats.update();
    // 立方体绕 x、y、z 轴旋转,速度由调试插件控制
    cube.rotation.x += controls.rotationSpeed;
    cube.rotation.y += controls.rotationSpeed;
    cube.rotation.z += controls.rotationSpeed;
    // 更新轨迹球控件的操作范围
    trackballControls.handleResize();
    // 更新物体位置
    trackballControls.update();
    // 开始渲染
    renderer.render(scene, camera);
  }

  // 实现动画效果
  function animate() {
    requestAnimationFrame(animate);
    render();
  }

  animate();
})
</script>

<style scoped>

</style>
